Skip to content

Update c++ compilation standard to 2014 from 2011. #191

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

xloem
Copy link
Contributor

@xloem xloem commented Jan 6, 2018

Requires a recent arm toolchain to be used.

This allows boost::hana and all sorts of crazy programming techniques.

Requires a recent arm toolchain to be used.
@fpistm
Copy link
Member

fpistm commented Jan 7, 2018

Hi @xloem
The current toolchain (arm gcc v6) is ok to support c++14.
I have to perform some build tests with that and ensure this will not bring some issue (backward compatibility with C++11)
I don't know boost::hana after some searches, it seems interesting.
Do you have any examples and the gain using it?

Thanks

@xloem
Copy link
Contributor Author

xloem commented Jan 7, 2018

boost::hana is basically the modern way for working with data structures that contain heterogenous types, or types themselves, in a generic way designed for compile-time evaluation.

So, for example, I am writing a class to hold an arbitrary block of multidimensional data. The dimensions the data spans may be of different types in the same block (dates of time, sample or sensor indices, positions in space). I'd like to include this information at compile-time so no runtime processing is needed to handle the data. But I'd also like to serialize and deserialize different kinds of these blocks, for storage and communication. I think I can use boost::hana to work with a tuple of dimensions and use either a compiletime set of types, or a runtime dynamic list of runtime type information, without having to worry about how to abstract the difference myself.

This would make my C++ code re-usable in both the tuned embedded environment, and in the high-powered database, even though very different assembly and underlying representations are generated.

Another use I've considered for boost::hana is to create a compile time expression evaluator that can also function at runtime, allowing things known to be precomputed, but things unknown to be adjusted while the system runs, using hana to work with a complex syntax tree of heterogenous types, objects of which have operator functions to make construction of an expression intuitive for the programmer. (float x_coord=solve(x_v, x_v^2 + y^2 = 1); //compiles like a literal if y is constexpr, produces a simple expression if y is not)

Boost::Hana is slow to compile, but newer MPL libraries are now in development that compile lightning fast. Upping the standards supported by the compiler will allow newer and newer ways to combine optimization with generalization to be used.

@xloem
Copy link
Contributor Author

xloem commented Jan 7, 2018

Here are a couple early examples from the hana manual:

// header stuff
#include <boost/hana.hpp>
namespace hana = boost::hana;

#include <cassert>
#include <iostream>
#include <string>

// some heterogenous types
struct Fish { std::string name; };
struct Cat  { std::string name; };
struct Dog  { std::string name; };

// a compile-time list of heterogenous objects
auto animals = hana::make_tuple(Fish{"Nemo"}, Cat{"Garfield"}, Dog{"Snoopy"});

using namespace hana::literals;
// Access tuple elements with operator[] instead of std::get.
Cat garfield = animals[1_c];
// Perform high level algorithms on tuples (this is like std::transform)
auto names = hana::transform(animals, [](auto a) {
  return a.name;
});

assert(hana::reverse(names) == hana::make_tuple("Snoopy", "Garfield", "Nemo"));
// 1. Give introspection capabilities to 'Person'
struct Person {
  BOOST_HANA_DEFINE_STRUCT(Person,
    (std::string, name),
    (int, age)
  );
};
// 2. Write a generic serializer (bear with std::ostream for the example)
auto serialize = [](std::ostream& os, auto const& object) {
  hana::for_each(hana::members(object), [&](auto member) {
    os << member << std::endl;
  });
};
// 3. Use it
Person john{"John", 30};
serialize(std::cout, john);
// output:
// John
// 30

@fpistm
Copy link
Member

fpistm commented Jan 7, 2018

Thanks for information.

@lacklustrlabs
Copy link
Contributor

I would love if we could upgrade to the C++14 standard, but I think it needs to be done with care.
As long as arduino.cc is using c++11 the core should, as fpistm said, be usable with c++11.

https://stackoverflow.com/questions/23980929/what-changes-introduced-in-c14-can-potentially-break-a-program-written-in-c1

[tldr] add a guideline saying that the core must be compatible with c++11

@fpistm
Copy link
Member

fpistm commented Jan 8, 2018

Thanks @lacklustrlabs
Main risk is the different behavior btw C++11 and C++14 mainly with Ardduino libraries.
Need more study/test and feedback on this PR.
Maybe one of the simplest way is to add a new menu to select the C++ standard (11 by default).
But this will add one other extra menu...

@xloem
Copy link
Contributor Author

xloem commented Jan 9, 2018

I examined these breaking changes in a little more depth, and I suspect it is reasonable to push forward with c++14 despite them.

  • Digit separators look like they will only cause a breaking change if a single quote character occurs between two digit characters with no whitespace. This is arguably poor style that should be removed from a public library anyway, and wouldn't be found in any code following a style standard.
  • Sized deallocation involves dynamic memory management, which is not used in arduino libraries due to the common lack of heap.
  • Relaxed requirements on constexpr member functions would be a significant breaking change for code using such functions, but the constexpr keyword was only introduced in c++11. The arduino core included with debian stretch still compiles to c++03, where this keyword doesn't exist. Mainstream libraries shouldn't be using it?
  • std::gets has been removed, but this function reads from stdin. There is no stdin in this environment.

Am I wrong about anything here?

@fpistm
Copy link
Member

fpistm commented Jan 9, 2018

You're right.
Moreover constexpr or std::gets will raised a build error so easily fixable.
I have to perform a release next week so I will not merge this PR now. I prefer add it to the next one and perform som build and test on all variant and some "standard" libraries

@fpistm fpistm self-assigned this Jan 11, 2018
@fpistm fpistm added the enhancement New feature or request label Jan 11, 2018
@fpistm
Copy link
Member

fpistm commented Jan 12, 2018

I've performed several builds and tests with this and seen any issue.
Also using several popular libraries.
Moreover teensy core use it since a while with success.
See arduino/Arduino#7090 (comment)

@lacklustrlabs
Copy link
Contributor

lacklustrlabs commented Jan 13, 2018

Suggestion: While the compiler.cpp.flags variable is changed, why not make the '-std=gnu++14' flag a variable itself?

This way it would be easy to change the -std setting in platform.local.txt without overriding anything else.

platform.local.txt:
compiler.cpp.std=c++17

platform.txt:

...
compiler.cpp.std=gnu++14
compiler.cpp.flags={compiler.extra_flags} -c {build.flags.optimize} {compiler.warning_flags} -std={compiler.cpp.std} -ffunction-sections -fdata-sections -nostdlib -fno-threadsafe-statics --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -MMD {compiler.stm.extra_include}
...

Without this the entire compiler.cpp.flags variable would have to be modified in platform.local.txt.

fpistm pushed a commit to fpistm/Arduino_Core_STM32 that referenced this pull request Jan 13, 2018
Requires a recent arm toolchain to be used.

Based on PR stm32duino#191 proposed by @xloem
Updated using @lacklustrlabs suggestion:
Make the '-std=gnu++14' flag a variable using 'compiler.cpp.flags' variable.
This way it is easy to change the -std setting in platform.local.txt without
overriding anything else.

platform.local.txt:
compiler.cpp.std=gnu++11

Signed-off-by: Frederic Pillon <[email protected]>
@xloem
Copy link
Contributor Author

xloem commented Jan 13, 2018

Replaced by #196

@xloem xloem closed this Jan 13, 2018
benwaffle pushed a commit to benwaffle/Arduino_Core_STM32 that referenced this pull request Apr 10, 2019
Requires a recent arm toolchain to be used.

Based on PR stm32duino#191 proposed by @xloem
Updated using @lacklustrlabs suggestion:
Make the '-std=gnu++14' flag a variable using 'compiler.cpp.flags' variable.
This way it is easy to change the -std setting in platform.local.txt without
overriding anything else.

platform.local.txt:
compiler.cpp.std=gnu++11

Signed-off-by: Frederic Pillon <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants